package zerrors

import "reflect"

type Empty struct{}

type String map[string]Empty

func NewString(items ...string) String {
	ss := String{}
	ss.Insert(items...)
	return ss
}

func StringsKeySet(theMap interface{}) String {
	v := reflect.ValueOf(theMap)
	ret := String{}

	for _, keyValue := range v.MapKeys() {
		ret.Insert(keyValue.Interface().(string))
	}
	return ret
}

func (s String) Insert(items ...string) String {
	for _, item := range items {
		s[item] = Empty{}
	}
	return s
}

func (s String) Delete(items ...string) String {
	// 一边遍历 map 一边删除
	for _, item := range items {
		delete(s, item)
	}
	return s
}

func (s String) Has(item string) bool {
	_, has := s[item]
	return has
}

func (s String) HasAll(items ...string) bool {
	for _, item := range items {
		if !s.Has(item) {
			return false
		}
	}
	return true
}

func (s String) Difference(s2 String) String {
	result := NewString()
	for key := range s {
		if !s2.Has(key) {
			result.Insert(key)
		}
	}
	return result
}

func (s String) Union(s2 String) String {
	result := NewString()

	for key := range s {
		result.Insert(key)
	}

	for key := range s2 {
		result.Insert(key)
	}
	return result
}

func (s String) Intersection(s2 String) String {
	result := NewString()
	for key := range s {
		if s2.Has(key) {
			result.Insert(key)
		}
	}
	return result
}

func (s String) IsSuperSet(s2 String) bool {
	for key := range s2 {
		if !s.Has(key) {
			return false
		}
	}
	return true
}

func (s String) Equal(s2 String) bool {
	return len(s) == len(s2) && s.IsSuperSet(s2)
}

func (s String) PopAny() (string, bool) {
	for key := range s {
		delete(s, key)
		return key, true
	}

	return "", false
}

func (s String) Len() int {
	return len(s)
}
